package org.example.mock;

import lombok.extern.slf4j.Slf4j;
import java.math.BigDecimal;
import java.sql.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * 用于生成 MoviesData 模拟数据并插入数据库的工具类
 * 适配 movies_data 表结构，可生成指定数量模拟电影数据并保存到数据库
 */
@Slf4j
public class MovieDataGenerator {
    private static final String DB_URL = "jdbc:mysql://192.168.10.102/changchengfilm?requireSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC";
    private static final String DB_USER = "root";
    private static final String DB_PASSWORD = "000000";
    private static final int BATCH_SIZE = 100;
    // 存储生成的模拟数据列表，按需使用
    private static final List<MoviesData> DATA_LIST = new ArrayList<>();
    private static final Random RANDOM = new Random();
    // 模拟的电影ID起始值，可根据实际场景调整
    private static int currentId = 1;
    // 预设电影名称，添加了中国电影
    private static final String[] TITLES = {
            "肖申克的救赎", "教父", "黑暗骑士", "泰坦尼克号", "复仇者联盟4：终局之战",
            "星球大战：原力觉醒", "阿凡达", "蜘蛛侠：英雄远征", "侏罗纪世界", "黑豹",
            "哈利波特与混血王子", "冰雪奇缘2", "钢铁侠3", "美国队长3", "玩具总动员4",
            "速度与激情7", "奇异博士", "银河护卫队", "雷神3：诸神黄昏", "侏罗纪公园",
            "怪物史莱克2", "超人总动员", "海底总动员", "狮子王", "指环王：王者归来",
            "加勒比海盗", "蜘蛛侠：英雄归来", "蝙蝠侠：黑暗骑士崛起", "星球大战外传：侠盗一号", "爱丽丝梦游仙境",
            "哈利波特与死亡圣器（下）", "星球大战：最后的绝地武士", "速度与激情8", "黑豹2", "毒液：致命守护者",
            "蚁人2：黄蜂女现身", "美国队长2", "雷神2：黑暗世界", "钢铁侠2", "哈利波特与火焰杯",
            "变形金刚", "独立日", "侏罗纪世界2", "蜘蛛侠3", "哈利波特与凤凰社",
            "哪吒之魔童降世", "流浪地球2", "满江红", "长津湖", "你好，李焕英",
            "唐人街探案3", "美人鱼", "我不是药神", "红海行动", "战狼2",
            "封神第一部", "独行月球", "悬崖之上", "送你一朵小红花", "少年的你",
            "我和我的祖国", "八佰", "白蛇：缘起", "误杀", "刺杀小说家"
    };
    // 预设导演名称，添加了中国导演
    private static final String[] DIRECTORS = {
            "弗兰克·德拉邦特", "弗朗西斯·福特·科波拉", "克里斯托弗·诺兰", "詹姆斯·卡梅隆", "安东尼·罗素", "乔·罗素",
            "J·J·艾布拉姆斯", "詹姆斯·卡梅隆", "乔·沃茨", "科林·特莱沃若", "瑞恩·库格勒",
            "大卫·叶茨", "克里斯·巴克", "珍妮弗·李", "沙恩·布莱克", "安东尼·罗素", "乔·罗素",
            "乔什·库雷", "温子仁", "斯科特·德瑞克森", "詹姆斯·古恩", "塔伊加·维迪提", "史蒂文·斯皮尔伯格",
            "安德鲁·亚当森", "凯利·阿斯博瑞", "布拉德·伯德", "安德鲁·斯坦顿", "罗杰·艾勒斯", "罗伯·明可夫", "彼得·杰克逊",
            "戈尔·维宾斯基", "乔·沃茨", "克里斯托弗·诺兰", "加里斯·爱德华斯", "蒂姆·波顿",
            "大卫·叶茨", "莱恩·约翰逊", "F·加里·格雷", "瑞恩·库格勒", "鲁本·弗雷斯彻",
            "佩顿·里德", "安东尼·罗素", "乔·罗素", "艾伦·泰勒", "乔恩·费儒", "迈克·内威尔",
            "迈克尔·贝", "罗兰·艾默里奇", "J·A·巴亚纳", "山姆·雷米", "大卫·叶茨",
            "饺子", "郭帆", "张艺谋", "陈凯歌", "徐峥",
            "陈思诚", "周星驰", "文牧野", "林超贤", "吴京",
            "乌尔善", "张吃鱼", "张艺谋", "韩延", "曾国祥",
            "陈凯歌", "管虎", "黄家康", "柯汶利", "路阳"
    };
    // 评分范围（0 - 10，保留1位小数）
    private static final BigDecimal MIN_SCORE = new BigDecimal("0.0");
    private static final BigDecimal MAX_SCORE = new BigDecimal("10.0");

    public static void main(String[] args) {
        log.info("开始生成 MoviesData 模拟数据并插入数据库");

        try {
            // 生成数据并插入数据库
            int count = 50;
            insertDataToDatabase(generateData(count));
            log.info("数据插入完成，共插入 {} 条记录", count);
        } catch (SQLException e) {
            log.error("数据库操作异常", e);
        } catch (Exception e) {
            log.error("发生未知异常", e);
        }
    }

    /**
     * 生成指定数量的 MoviesData 模拟数据
     * @param count 要生成的数据条数
     * @return 包含模拟数据的 List<MoviesData>
     */
    private static List<MoviesData> generateData(int count) {
        List<MoviesData> dataList = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            MoviesData data = new MoviesData();
            data.setMovieId(currentId++); // 修正：使用int类型的movieId
            // 从预设电影名中随机选取
            data.setMovieName(TITLES[RANDOM.nextInt(TITLES.length)]);
            // 随机生成评分（0.0 - 10.0，保留1位小数）
            BigDecimal score = new BigDecimal(RANDOM.nextDouble() * 10)
                    .setScale(1, BigDecimal.ROUND_HALF_UP);
            data.setScore(score);
            // 随机生成投票人数（100 - 10000）
            data.setVoteCount(RANDOM.nextInt(9901) + 100);
            // 随机生成上映日期（近10年示例，可调整）
            long randomTime = System.currentTimeMillis() - RANDOM.nextInt(365 * 10) * 24 * 60 * 60 * 1000L;
            data.setReleaseDate(new Date(randomTime));
            // 随机生成电影时长（60 - 240分钟）
            data.setRuntime(RANDOM.nextInt(181) + 60);
            // 从预设导演中随机选取
            data.setDirector(DIRECTORS[RANDOM.nextInt(DIRECTORS.length)]);
            // 简单生成电影简介
            data.setDescription("这是电影《" + data.getMovieName() + "》的简介...");
            // 简单生成IMDB标识
            data.setImdbId("tt" + (100000 + RANDOM.nextInt(900000)));

            dataList.add(data);
            DATA_LIST.add(data);
        }
        return dataList;
    }

    /**
     * 将生成的电影数据插入数据库
     * @param moviesDataList 电影数据列表
     * @throws SQLException 如果数据库操作失败
     */
    private static void insertDataToDatabase(List<MoviesData> moviesDataList) throws SQLException {
        // 修改SQL语句中的列名
        String sql = "INSERT INTO movies_data (movie_id, movie_name, score, vote_count, release_date, runtime, director, description, imdb_id) " +
                "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";

        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            // 启用批处理模式
            conn.setAutoCommit(false);

            for (MoviesData data : moviesDataList) {
                pstmt.setInt(1, data.getMovieId());
                pstmt.setString(2, data.getMovieName());
                pstmt.setBigDecimal(3, data.getScore());
                pstmt.setInt(4, data.getVoteCount());
                pstmt.setTimestamp(5, new Timestamp(data.getReleaseDate().getTime()));
                pstmt.setInt(6, data.getRuntime());
                pstmt.setString(7, data.getDirector());
                pstmt.setString(8, data.getDescription());
                pstmt.setString(9, data.getImdbId());

                pstmt.addBatch();

                // 每 BATCH_SIZE 条记录执行一次批处理
                if ((moviesDataList.indexOf(data) + 1) % BATCH_SIZE == 0) {
                    pstmt.executeBatch();
                }
            }

            // 执行剩余的批处理
            pstmt.executeBatch();
            // 提交事务
            conn.commit();

            log.info("成功插入 {} 条电影数据到数据库", moviesDataList.size());
        } catch (SQLException e) {
            log.error("插入数据到数据库失败", e);
            // 回滚事务
            throw e;
        }
    }

    /**
     * 内部类：电影数据模型
     */
    public static class MoviesData {
        private int movieId;
        private String movieName;
        private BigDecimal score;
        private int voteCount;
        private Date releaseDate;
        private int runtime;
        private String director;
        private String description;
        private String imdbId;

        // Getters and Setters
        public int getMovieId() {
            return movieId;
        }

        public void setMovieId(int movieId) {
            this.movieId = movieId;
        }

        public String getMovieName() {
            return movieName;
        }

        public void setMovieName(String movieName) {
            this.movieName = movieName;
        }

        public BigDecimal getScore() {
            return score;
        }

        public void setScore(BigDecimal score) {
            this.score = score;
        }

        public int getVoteCount() {
            return voteCount;
        }

        public void setVoteCount(int voteCount) {
            this.voteCount = voteCount;
        }

        public Date getReleaseDate() {
            return releaseDate;
        }

        public void setReleaseDate(Date releaseDate) {
            this.releaseDate = releaseDate;
        }

        public int getRuntime() {
            return runtime;
        }

        public void setRuntime(int runtime) {
            this.runtime = runtime;
        }

        public String getDirector() {
            return director;
        }

        public void setDirector(String director) {
            this.director = director;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        public String getImdbId() {
            return imdbId;
        }

        public void setImdbId(String imdbId) {
            this.imdbId = imdbId;
        }
    }
}